package com.aiwei.tdjk.bean;

import com.aiwei.tdjk.bean.annotation.Log;
import com.aiwei.tdjk.entity.User;
import com.aiwei.tdjk.utils.UserUtil;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * Created by yanfeng on 2017/9/28.
 */

@Aspect
public class SystemLogAspect {

//    private  static  final Logger logger = LoggerFactory.getLogger(SystemLogAspect. class);

    private static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(SystemLogAspect.class);

    //Controller层切点
    @Pointcut("execution (* com.aiwei.tdjk.controller..*.*(..))")
    public  void controllerAspect() {
    }

    /**
     * 前置通知 用于拦截Controller层记录用户的操作
     *
     * @param joinPoint 切点
     */
    @Before("controllerAspect()")
    public void doBefore(JoinPoint joinPoint) {
        System.out.println("==========执行controller前置通知===============");
        if(logger.isInfoEnabled()){
            logger.info("before " + joinPoint);
        }
    }



    /**
     * 后置通知 用于拦截Controller层记录用户的操作
     *
     * @param joinPoint 切点
     */
    @After("controllerAspect()")
    public  void after(JoinPoint joinPoint) {

       HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpSession session = request.getSession();
        //读取session中的用户
        // User user = (User) session.getAttribute("user");
        //请求的IP
        String ip = request.getRemoteAddr();
        User user = UserUtil.getUserFromSession();

        if (user==null) return;

        try {

            String targetName = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            Object[] arguments = joinPoint.getArgs();
            Class targetClass = Class.forName(targetName);
            Method[] methods = targetClass.getMethods();
            String operationType = "";
            String operationName = "";
            for (Method method : methods) {
                if (method.getName().equals(methodName)) {
                    Class[] clazzs = method.getParameterTypes();
                    if (clazzs.length == arguments.length) {
                        //todo
                        Log methodAnnotation = method.getAnnotation(Log.class);
                        if (methodAnnotation!=null){
                            operationType = methodAnnotation.operationType();
                            operationName = methodAnnotation.operationName();
                        }

                        break;
                    }
                }
            }
            //*========控制台输出=========*//
            logger.info("=====controller后置通知开始====="+ LocalDateTime.now().toString());
            logger.info("请求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType);
            logger.info("方法参数:" + getArgs(joinPoint));
            if (StringUtils.isNotEmpty(operationName)){
                logger.info("方法描述:" + operationName);

            }

            logger.info("请求人:" + user.getUsername());
            logger.info("请求IP:" + ip);
            //*========数据库日志=========*//
//            SystemLog log = new SystemLog();
//            log.setId(UUID.randomUUID().toString());
//            log.setDescription(operationName);
//            log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType);
//            log.setLogType((long)0);
//            log.setRequestIp(ip);
//            log.setExceptioncode( null);
//            log.setExceptionDetail( null);
//            log.setParams( null);
//            log.setCreateBy(user.getName());
//            log.setCreateDate(new Date());
//            //保存数据库
//            systemLogService.insert(log);
            logger.info("=====controller后置通知结束====="+LocalDateTime.now().toString());
        }  catch (Exception e) {
            //记录本地异常日志
            logger.error("==后置通知异常==");
            logger.error("异常信息:{}", e);
        }
    }

    //获取所有的参数名和值，组装为String
    private String getArgs(JoinPoint point) {
        String[] parameterNames = ((MethodSignature) point.getSignature()).getParameterNames();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < parameterNames.length; i++) {
            sb.append(parameterNames[i] + ":" + point.getArgs()[i].toString() + "; ");
        }

        return sb.toString();
    }
}
